package com.oocl.client;

import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;

import javax.swing.JOptionPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

import com.oocl.client.callback.ChangeFrameCallback;
import com.oocl.client.callback.ProtocolFinishProcessCallback;
import com.oocl.client.callback.ProtocolSendCallback;
import com.oocl.client.callback.WindowCloseCallback;
import com.oocl.client.process.ProtocolReceiver;
import com.oocl.client.process.ProtocolSender;
import com.oocl.client.process.impl.ProtocolReceiverImpl;
import com.oocl.client.process.impl.ProtocolSenderImpl;
import com.oocl.client.ui.BaseFrame;
import com.oocl.client.ui.impl.ChatFrame;
import com.oocl.client.ui.impl.LoginFrame;
import com.oocl.client.ui.impl.RegisterFrame;
import com.oocl.client.util.JacksonUtil;
import com.oocl.client.util.Logger;
import com.oocl.qq.protocol.Protocol;

/**
 * QQClient QQ客户端
 * 实现接口：(目的是实现)
 *   * ChangeFrameCallback： -----> 窗口切换回调
 *   * ProtocolSendCallback -----> 消息发送器 发送完成  后的回调
 *   * WindowCloseCallback： 窗口关闭回调 ----> 让Socket关闭
 * 
 * 
 * @author WUJA13
 * 
 */
public class QQClient implements ChangeFrameCallback,
		ProtocolFinishProcessCallback, ProtocolSendCallback,
		WindowCloseCallback {

	Socket socket = null;
	InputStream in;
	OutputStream out;
	ObjectOutputStream objectOut;
	ObjectInputStream objectIn;

	ProtocolReceiver receiver;///消息接收者
	ProtocolSender sender;///消息发送者
	BaseFrame curFrame;///聊天窗口（消息接收者）

	public QQClient(int port) {
		try {
			///初始化
			
			///新建socket
			this.socket = new Socket("10.222.29.174", port);

			/// 打开连接
			in = this.socket.getInputStream();
			out = this.socket.getOutputStream();
			objectOut = new ObjectOutputStream(out);
			objectIn = new ObjectInputStream(in);
			
		////构造 ProtocolReceiver 和 ProtocolSender
			this.sender = new ProtocolSenderImpl(this);

			///初始，将登录界面
			LoginFrame loginFrame = new LoginFrame();
			loginFrame.setChangeFrameCallback(this);
			loginFrame.setProtocolSender(this.sender);
			
			this.curFrame = loginFrame;
			
			ProtocolReceiverImpl receiverImpl = new ProtocolReceiverImpl();
			receiverImpl.setLogin(loginFrame);///传入登录界面
			this.receiver = receiverImpl;
			
			///始终监听数据
			alwaysListen();
			
		} catch (IOException e) {
			Logger.log("客户端已断开连接");
			int option = JOptionPane.showConfirmDialog( 
	                  this.curFrame, "客户端已断开连接", "提示 ",JOptionPane.YES_OPTION);
			System.exit(0);
		}
	}

	//上线了，持续监听Protocol
	private void alwaysListen() throws IOException {
		System.out.println("客户端已上线");
		while (!this.socket.isClosed()) {
			try {
				String jsonStr = (String) this.objectIn.readObject();
				if(jsonStr ==null || jsonStr.length()==0)
					continue;
				Protocol p = JacksonUtil.fromJsonToObject(jsonStr, Protocol.class);
				if (p != null)
					this.receiver.receiveProtocol(p);
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			}
		}
	}

	@Override
	public void startSend() {
		////我是QQClient， 我允许发送器发送消息
		this.sender.canSendProtocol(this.objectOut);
	}

	@Override
	public void finishSend() {
		////消息成功发生出去了
	}

	@Override
	public void finishProcessProtocol() {
		//// 别人发来的消息，我成功处理了
	}

	@Override
	public void changeFrame(BaseFrame newFrame) {
		///切换窗口回调
		///从 LoginFrame 到 ChatFrame
		if (newFrame instanceof ChatFrame) {
			ChatFrame chatFrame = (ChatFrame) newFrame;
			chatFrame.setWindowCloseCallback(this);
			chatFrame.setProtocolSender(this.sender);
			ProtocolReceiverImpl receiverImpl = (ProtocolReceiverImpl) this.receiver;
			receiverImpl.setChatOperator(chatFrame);
			this.curFrame.setVisible(false);
			this.curFrame = newFrame;
		}else if(newFrame instanceof RegisterFrame){
			///LoginFrame 到 RegisterFrame
			RegisterFrame registerFrame = (RegisterFrame) newFrame;
			registerFrame.setProtocolSender(this.sender);
			ProtocolReceiverImpl receiverImpl = (ProtocolReceiverImpl) this.receiver;
			receiverImpl.setRegister(registerFrame);
			this.curFrame.setVisible(false);
			this.curFrame = newFrame;
		}else if(newFrame instanceof LoginFrame){			
			///RegisterFrame 到 LoginFrame
			newFrame.setVisible(true);
			this.curFrame.setVisible(false);
			this.curFrame = newFrame;
		}
	}

	@Override
	public void closeWindow() {
		try {
			this.objectIn.close();
			this.objectOut.close();
			this.socket.close();
			System.out.println("QQ客户端成功关闭");
		} catch (IOException e) {
			System.out.println("QQ客户端异常关闭！");
//			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		int port =  8001;
		QQClient client = new QQClient(port);
	}

}
